<?php
declare (strict_types=1);

namespace app\service\logic\common\user;

use app\exception\LogicException;
use app\model\communal\ExpertStatisticsModel;
use app\model\communal\UserStatisticsModel;
use app\service\logic\BaseService;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\Model;

final class ExpertStatisticsService extends BaseService
{
    protected string $modelClassName = 'ExpertStatisticsModel';

    /**
     * 查找单挑记录可能为空
     *
     * @param $params
     * @return UserStatisticsModel|array|mixed|Model
     */
    public function getSimpleOrEmpty($params)
    {
        return UserStatisticsModel::findOrEmpty($params['id']);
    }

    /**
     * 获取可用金额
     *
     * @param $expertId
     * @return mixed|string
     */
    public function getAmountAvailableCountByExpertId($expertId)
    {
        $amountAvailableCount = '0';
        $model = ExpertStatisticsModel::findOrEmpty($expertId);
        if (!$model->isEmpty()) {
            $amountAvailableCount = $model['amount_available_count'];
        }

        return $amountAvailableCount;
    }

    /**
     * 获取金额相关
     *
     * @param $expertId
     * @return string[]
     */
    public function getAmountByExpertId($expertId)
    {
        $amountCount = '0';
        $amountAvailableCount = '0';
        $amountFreezeCount = '0';
        $model = ExpertStatisticsModel::findOrEmpty($expertId);
        if (!$model->isEmpty()) {
            $amountCount = $model['amount_count'];
            $amountAvailableCount = $model['amount_available_count'];
            $amountFreezeCount = $model['amount_freeze_count'];
        }

        return [
            'amount_count' => $amountCount,
            'amount_available_count' => $amountAvailableCount,
            'amount_freeze_count' => $amountFreezeCount,
        ];
    }

    /**
     * 锁定可用金额
     *
     * @param $expertId
     * @param $amountCount
     * @return bool
     * @throws DataNotFoundException
     * @throws LogicException
     * @throws ModelNotFoundException
     */
    public function freezeAmount($expertId, $amountCount)
    {
        $model = $this->getSimpleDetail(['id' => $expertId]);

        if ($amountCount > $model['amount_available_count']) {
            throw new LogicException('可用余额不足');
        }

        $availableCount = bcsub($model['amount_available_count'], $amountCount, 2);
        $freezeCount = bcadd($model['amount_freeze_count'], $amountCount, 2);
        return $model->save(['amount_available_count' => $availableCount, 'amount_freeze_count' => $freezeCount]);
    }

    /**
     * 解冻金额
     *
     * @param $expertId
     * @param $amountCount
     * @return bool
     * @throws DataNotFoundException
     * @throws LogicException
     * @throws ModelNotFoundException
     */
    public function unfreezeCoin($expertId, $amountCount)
    {
        $model = $this->getSimpleDetail(['id' => $expertId]);

        if ($amountCount > $model['amount_freeze_count']) {
            throw new LogicException('锁定金额不足');
        }

        $availableCount = bcadd($model['amount_available_count'], $amountCount, 2);
        $freezeCount = bcsub($model['amount_freeze_count'], $amountCount, 2);
        return $model->save(['amount_available_count' => $availableCount, 'amount_freeze_count' => $freezeCount]);
    }

    /**
     * 消耗冻结元心币&&产生元心币明细
     *
     * @param $expertId
     * @param $amountCount
     * @param $amountType
     * @throws DataNotFoundException
     * @throws LogicException
     * @throws ModelNotFoundException
     */
    public function consumeFreezeCoin($expertId, $amountCount, $amountType)
    {
        $model = $this->getSimpleDetail(['id' => $expertId]);

        if ($amountCount > $model['amount_freeze_count']) {
            throw new LogicException('锁定金额不足');
        }

        if ($amountCount > 0) {
            // 类型 1 企业订单结算 2 个人订单结算 3 提现
            $amountTypeMap = [1 => '企业订单结算', 2 => '个人订单结算', 3 => '返现'];
            $freezeCount = bcsub($model['amount_freeze_count'], $amountCount, 2);
            $totalCoinCount = bcadd($model['amount_available_count'], $freezeCount, 2);
            $model->save(['amount_count' => $totalCoinCount, 'amount_freeze_count' => $freezeCount]);
            invoke(ExpertAmountService::class)->create([
                'expert_id' => $expertId,
                'amount_count' => $amountCount,
                'amount_balance' => $totalCoinCount,
                'remark' => $amountTypeMap[$amountType] ?? '',
                'type' => $amountType
            ]);
        }
    }
}
